package nayasis.common.db.manager.transaction;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import nayasis.common.db.manager.connection.ConnectionManager;
import nayasis.common.db.manager.connection.WrapperConnection;

/**
 * Connection 객체 관리용 ThreadLocal
 *
 * @author nayasis
 *
 */
public final class ConnectionThreadLocal {

	private ConnectionThreadLocal() {}

	// 전역변수
	private static final ThreadLocal<Map<String, WrapperConnection>> threadLocal = new ThreadLocal<Map<String, WrapperConnection>>() {
	     public Map<String, WrapperConnection> initialValue() {
	           return new HashMap<String, WrapperConnection>();
	     }
	};

	/**
	 * dbSpec으로 저장된 DB Connection을 가져온다.
	 *
	 * @param dbSpec dbSpec
	 * @return dbSpec으로 저장된 object
	 */
	public static WrapperConnection get( String dbSpec ) {
		return threadLocal.get().get( dbSpec );
	}

	/**
	 * dbSpec으로 DB Connection을 저장한다.
	 *
	 * @param dbSpec   dbSpec
	 * @param connection 저장할 DB Connection
	 */
	public static void set( WrapperConnection connection ) {
		threadLocal.get().put( connection.getDbSpec(), connection );
	}

	/**
	 * dbSpec으로 저장된 DB Connection을 삭제한다.
	 *
	 * @param dbSpec dbSpec
	 * @return 삭제 성공여부
	 */
	public static boolean remove( String dbSpec ) {

		WrapperConnection conn = get( dbSpec );
		
		return remove( conn );

	}

	/**
	 * DB Connection을 삭제한다.
	 *
	 * @param dbSpec dbSpec
	 * @return 삭제 성공여부
	 */
	public static boolean remove( WrapperConnection connection ) {

		if( ConnectionManager.closeConnection(connection) ) {

			threadLocal.get().remove( connection.getDbSpec() );

			return true;

		}

		return false;
		
	}

	/**
	 * dbSpec으로 저장된 DB Connection이 존재하는지 여부를 확인한다.
	 *
	 * @param dbSpec dbSpec
	 * @return dbSpec으로 저장된 DB Connection 존재여부
	 */
	public static boolean contains( String dbSpec ) {
		return threadLocal.get().containsKey( dbSpec );
	}

	/**
	 * DB Connection이 존재하는지 여부를 확인한다.
	 *
	 * @param connection 찾고자 하는 DB Connection
	 * @return DB Connection 존재여부
	 */
	public static boolean contains( WrapperConnection connection ) {
		return threadLocal.get().containsValue( connection );
	}

	/**
	 * 내부 참조 데이터를 모두 제거한다.
	 */
	public static void clear() {
		threadLocal.get().clear();
	}

	/**
	 * 저장된 dbSpec의 목록을 얻는다.
	 *
	 * @return dbSpec 목록
	 */
	public static List<String> getDbSpecList() {

		Set<String> keySet = threadLocal.get().keySet();

		List<String> result = new ArrayList<String>();

		for( String key : keySet ) {
			result.add( key );
		}

		return result;

	}

	/**
	 * 저장된 모든 DB Connection 목록을 가져온다.
	 *
	 * @return DB Connection 목록
	 */
	public static List<WrapperConnection> getConnectionList() {

		Set<String> keySet = threadLocal.get().keySet();

		List<WrapperConnection> result = new ArrayList<>();

		for( String key : keySet ) {
			result.add( get(key) );
		}

		return result;

	}

}
